package org.example.redpacket.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.time.LocalDateTime;

/**
 * 当前类只是为了补充AOP的部分，项目中只是为了打印方法执行时间
 *
 * @author: hero生仔
 */
@Component
@Aspect
public class WebLogAspect {
    private static final Logger LOGGER = LoggerFactory.getLogger(WebLogAspect.class);

    /**
     * "public" 代表修饰符，省略时可以代表所有的修饰符
     * "*" 代表的是返回值，用 "*" 匹配任意类型
     * "org.example.redpacket.controller" 匹配目标类，匹配包名及其子包的所有类
     * "*" 代表类下所有方法
     * "(..)" 代表匹配有任意参数的方法，"()" 代表没有参数的方法
     */
    @Pointcut(value = "execution(public * org.example.redpacket.controller.*.*(..))")
    public void webLog() {
    }

    @Around("webLog()")
    public Object aroundAopOfLog(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取方法名和入参信息
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        LOGGER.info("方法名为：{},方法入参为：{}", methodName, args);

        LocalDateTime start = LocalDateTime.now();
        Object proceed;
        try {
            proceed = joinPoint.proceed();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        LocalDateTime end = LocalDateTime.now();
        LOGGER.info("方法耗时为 {} ms", Duration.between(start, end).toMillis());
        return proceed;
    }
}
